package xiaohu.day5.HJ50;

import java.util.*;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    // 存放算数优先级
    public static HashMap<Character, Integer> map = new
            HashMap<Character, Integer>() { //这里泛型必须写
                // 声明优先级
                {
                    put('-', 1);
                    put('+', 1);
                    put('*', 2);
                    put('/', 2);
                }
            };

    public static boolean isNumber(char c) {
        return Character.isDigit(c);
    }

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String str = sc.nextLine();
        System.out.println(calculate(str));
    }

    public static int calculate(String str) {
        // 处理特殊括号,注意替换后的值，不要写错了。且replace后要重新赋值给str
        str = str.replaceAll("\\[", "(").replaceAll("\\{", "(").replaceAll("\\]",
                ")").replaceAll("\\}", ")").replaceAll(" ", "");

        // 处理负数
        for (int i = 0; i < str.length(); i++) {
            if (str.charAt(i) == '-') {
                if (i == 0 || str.charAt(i - 1) == '+' || str.charAt(i - 1) == '-' ||
                        str.charAt(i - 1) == '*' || str.charAt(i - 1) == '/' ||
                        str.charAt(i - 1) == '('){
                    //str.substring(i + 1)表示从i+1截取到末尾
                    str = str.substring(0, i) + "#" + str.substring(i + 1);
                }

            }
        }

        //初始化两个栈，分别存放运算术和运算符
        Stack<Integer> nums = new Stack<>();
        Stack<Character> opts = new Stack<>();
        char[] cs = str.toCharArray();
        int n = cs.length;
        for (int i = 0; i < n; i++) {
            char c = cs[i];

            //判断负数、左括号、右括号、普通运算数、+-*/
            if (c == '#') {
                int j = i + 1, v = 0; // 运算符往后一位，所以是i+1，正数会直接是j=i
                while (j < n && isNumber(cs[j])) {
                    v = v * 10 + cs[j++] - '0';
                }
                nums.add(-v);
                i = j - 1; //多位数处理
            } else if (c == '(') {
                opts.add(c);
            } else if (c == ')') {
                // 计算括号内的数据，直到栈顶为（为止
                while (opts.peek() != '(') {
                    cal(nums, opts);
                }
                opts.pop(); //左括号出栈--易错点
            } else {
                // 正数
                if (isNumber(c)) {
                    int j = i, v = 0;
                    while (j < n && isNumber(cs[j])) {
                        v = v * 10 + cs[j++] - '0';
                    }
                    nums.add(v);
                    i = j - 1;
                } else {
                    while(!opts.isEmpty() && opts.peek() != '('){
                        char prev = opts.peek();
                        if(map.get(prev) >= map.get(c)){
                            cal(nums,opts);
                        }else{
                            break;
                        }
                    }
                    opts.add(c);
                }

            }
        }

        while (!opts.isEmpty()) {
            cal(nums, opts);
        }
        //计算到最后的数据、因为每次计算都会把数据存入nums栈中，所以取栈顶即可
        return nums.peek();
    }

    public static void cal(Stack<Integer> nums, Stack<Character> opts) {
        if (nums.isEmpty() || nums.size() < 2) {
            return;
        }

        if (opts.isEmpty()) {
            return;
        }
        //b为右操作数
        int b = nums.pop(), a = nums.pop();
        char op = opts.pop();
        int ans = 0;
        switch (op) {
            case '+' :
                ans = a + b;
                break;
            case '-':
                ans = a - b;
                break;
            case '*':
                ans = a * b;
                break;
            case '/':
                ans = a / b;
                break;
            default:
                break;
        }
        nums.add(ans);
    }

}
